package com.example.smartagrisys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartagrisys.common.ResultCode;
import com.example.smartagrisys.dto.LandDTO;
import com.example.smartagrisys.dto.LandQueryDTO;
import com.example.smartagrisys.entity.Land;
import com.example.smartagrisys.entity.User;
import com.example.smartagrisys.exception.BusinessException;
import com.example.smartagrisys.mapper.LandMapper;
import com.example.smartagrisys.service.LandService;
import com.example.smartagrisys.service.UserService;
import com.example.smartagrisys.vo.LandVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 土地服务实现
 */
@Slf4j
@Service
public class LandServiceImpl extends ServiceImpl<LandMapper, Land> implements LandService {

    @Resource
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long add(LandDTO landDTO, Long farmerId) {
        // 检查用户是否为农户角色
        User farmer = checkFarmer(farmerId);

        // 创建土地实体
        Land land = new Land();
        BeanUtils.copyProperties(landDTO, land);
        land.setFarmerId(farmerId);
        land.setStatus(0); // 默认闲置状态

        // 保存土地信息
        save(land);

        log.info("农户 {} 添加土地：{}", farmerId, land.getId());
        return land.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(LandDTO landDTO, Long farmerId) {
        // 检查土地是否存在
        Land land = getById(landDTO.getId());
        if (land == null) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "土地不存在");
        }

        // 检查是否为土地所有者
        if (!land.getFarmerId().equals(farmerId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "您无权修改此土地信息");
        }

        // 更新土地信息
        BeanUtils.copyProperties(landDTO, land);
        
        log.info("农户 {} 更新土地：{}", farmerId, land.getId());
        return updateById(land);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id, Long farmerId) {
        // 检查土地是否存在
        Land land = getById(id);
        if (land == null) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "土地不存在");
        }

        // 检查是否为土地所有者
        if (!land.getFarmerId().equals(farmerId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "您无权删除此土地");
        }

        // 检查土地状态
        if (land.getStatus() == 1) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "土地正在种植中，无法删除");
        }

        log.info("农户 {} 删除土地：{}", farmerId, id);
        return removeById(id);
    }

    @Override
    public LandVO getDetail(Long id) {
        // 获取土地信息
        Land land = getById(id);
        if (land == null) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "土地不存在");
        }

        // 获取农户信息
        User farmer = userService.getById(land.getFarmerId());

        // 转换为VO
        LandVO landVO = convertToVO(land);
        if (farmer != null) {
            landVO.setFarmerName(farmer.getNickname());
        }

        return landVO;
    }

    @Override
    public Page<LandVO> page(LandQueryDTO queryDTO) {
        // 创建分页对象
        Page<Land> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        // 构建查询条件
        LambdaQueryWrapper<Land> wrapper = new LambdaQueryWrapper<>();

        // 按农户ID查询
        if (queryDTO.getFarmerId() != null) {
            wrapper.eq(Land::getFarmerId, queryDTO.getFarmerId());
        }

        // 按名称模糊查询
        if (StringUtils.hasText(queryDTO.getName())) {
            wrapper.like(Land::getName, queryDTO.getName());
        }

        // 按位置模糊查询
        if (StringUtils.hasText(queryDTO.getLocation())) {
            wrapper.like(Land::getLocation, queryDTO.getLocation());
        }

        // 按土地类型查询
        if (queryDTO.getType() != null) {
            wrapper.eq(Land::getType, queryDTO.getType());
        }

        // 按土壤类型查询
        if (queryDTO.getSoilType() != null) {
            wrapper.eq(Land::getSoilType, queryDTO.getSoilType());
        }

        // 按状态查询
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Land::getStatus, queryDTO.getStatus());
        }

        // 按种植作物模糊查询
        if (StringUtils.hasText(queryDTO.getCurrentCrop())) {
            wrapper.like(Land::getCurrentCrop, queryDTO.getCurrentCrop());
        }

        // 按面积范围查询
        if (queryDTO.getAreaMin() != null) {
            wrapper.ge(Land::getArea, queryDTO.getAreaMin());
        }
        if (queryDTO.getAreaMax() != null) {
            wrapper.le(Land::getArea, queryDTO.getAreaMax());
        }

        // 按土壤肥力查询
        if (queryDTO.getFertility() != null) {
            wrapper.eq(Land::getFertility, queryDTO.getFertility());
        }

        // 按灌溉条件查询
        if (queryDTO.getIrrigation() != null) {
            wrapper.eq(Land::getIrrigation, queryDTO.getIrrigation());
        }

        // 按创建时间降序
        wrapper.orderByDesc(Land::getCreateTime);

        // 执行分页查询
        page = page(page, wrapper);

        // 转换结果
        Page<LandVO> resultPage = new Page<>();
        BeanUtils.copyProperties(page, resultPage, "records");
        
        // 获取所有农户ID
        List<Long> farmerIds = page.getRecords().stream()
                .map(Land::getFarmerId)
                .distinct()
                .collect(Collectors.toList());
        
        // 批量查询农户信息
        List<User> farmers = farmerIds.isEmpty() ? Collections.emptyList() :
                userService.listByIds(farmerIds);
        
        // 转换为VO列表
        List<LandVO> records = page.getRecords().stream()
                .map(land -> {
                    LandVO vo = convertToVO(land);
                    // 设置农户名称
                    farmers.stream()
                            .filter(user -> user.getId().equals(land.getFarmerId()))
                            .findFirst()
                            .ifPresent(user -> vo.setFarmerName(user.getNickname()));
                    return vo;
                })
                .collect(Collectors.toList());
        
        resultPage.setRecords(records);
        return resultPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status, Long farmerId) {
        // 检查土地是否存在
        Land land = getById(id);
        if (land == null) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "土地不存在");
        }

        // 检查是否为土地所有者
        if (!land.getFarmerId().equals(farmerId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "您无权修改此土地状态");
        }

        // 检查状态是否有效
        if (status < 0 || status > 2) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "无效的土地状态");
        }

        // 更新状态
        land.setStatus(status);
        
        log.info("农户 {} 更新土地 {} 状态为：{}", farmerId, id, status);
        return updateById(land);
    }

    @Override
    public Page<LandVO> getFarmerLands(Long farmerId, Integer pageNum, Integer pageSize) {
        // 检查用户是否为农户角色
        User farmer = checkFarmer(farmerId);
        
        // 创建查询对象
        LandQueryDTO queryDTO = new LandQueryDTO();
        queryDTO.setFarmerId(farmerId);
        queryDTO.setPageNum(pageNum);
        queryDTO.setPageSize(pageSize);
        
        return page(queryDTO);
    }

    @Override
    public String getLandTypeName(Integer type) {
        if (type == null) {
            return "未知";
        }
        
        switch (type) {
            case 1: return "水田";
            case 2: return "旱地";
            case 3: return "果园";
            case 4: return "菜地";
            case 5: return "其他";
            default: return "未知";
        }
    }

    @Override
    public String getSoilTypeName(Integer soilType) {
        if (soilType == null) {
            return "未知";
        }
        
        switch (soilType) {
            case 1: return "砂质土";
            case 2: return "粘土";
            case 3: return "壤土";
            case 4: return "石灰土";
            case 5: return "其他";
            default: return "未知";
        }
    }

    @Override
    public String getLandStatusName(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        switch (status) {
            case 0: return "闲置";
            case 1: return "已种植";
            case 2: return "已收获";
            default: return "未知";
        }
    }

    @Override
    public String getFertilityName(Integer fertility) {
        if (fertility == null) {
            return "未知";
        }
        
        switch (fertility) {
            case 1: return "低";
            case 2: return "中";
            case 3: return "高";
            default: return "未知";
        }
    }

    @Override
    public String getIrrigationName(Integer irrigation) {
        if (irrigation == null) {
            return "未知";
        }
        
        switch (irrigation) {
            case 1: return "差";
            case 2: return "一般";
            case 3: return "好";
            default: return "未知";
        }
    }

    /**
     * 检查用户是否为农户角色
     */
    private User checkFarmer(Long userId) {
        // 查询用户信息
        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "用户不存在");
        }
        
        // 检查用户角色是否为农户
        if (!"farmer".equals(user.getRole())) {
            throw new BusinessException(ResultCode.FORBIDDEN, "只有农户才能管理土地");
        }
        
        return user;
    }

    /**
     * 将实体转换为VO
     */
    private LandVO convertToVO(Land land) {
        LandVO vo = new LandVO();
        BeanUtils.copyProperties(land, vo);
        
        // 设置类型名称
        vo.setTypeName(getLandTypeName(land.getType()));
        vo.setSoilTypeName(getSoilTypeName(land.getSoilType()));
        vo.setStatusName(getLandStatusName(land.getStatus()));
        vo.setFertilityName(getFertilityName(land.getFertility()));
        vo.setIrrigationName(getIrrigationName(land.getIrrigation()));
        
        return vo;
    }
} 